import GraphVertex from '../res/data-structures/graph/GraphVertex.js';
import GraphEdge from '../res/data-structures/graph/GraphEdge.js';
import Graph from '../res/data-structures/graph/Graph.js';
import hamiltonianCycle from '../res/graph/hamiltonian-cycle/hamiltonianCycle.js';
//样图数据
let exampleGraph=[
    {
       "nodeNum":20,
       "nodeLocation":[
           {
               x:-4.5,y:7
           },
           {
               x:4.5,y:7
           },
           {
               x:-3.0,y:5.1
           },
           {
               x:3.0,y:5.1
           },
           {
               x:0,y:4.3
           },
           {
               x:-3.7,y:2.6
           },
           {
               x:3.7,y:2.6
           },
           {
               x:0,y:2.5
           },
           {
               x:-1.7,y:1.7
           },
           {
               x:1.7,y:1.7
           },
           {
               x:-1,y:0
           },
           {
               x:1,y:0
           },
           {
               x:-4.9,y:-0.4
           },
           {
               x:4.9,y:-0.4
           },
           {
               x:-7.0,y:-0.9
           },
           {
               x:7.0,y:-0.9
           },
           {
               x:-2.1,y:-1.3
           },
           {
               x:2.1,y:-1.3
           },
           {
               x:0,y:-3.3
           },
           {
               x:0,y:-5.5
           },
       ],
       "edgeList":[
            {
                "source":0,
                "target":2
            },
            {
                "source":0,
                "target":14
            },
            {
                "source":0,
                "target":1
            },
            {
                "source":1,
                "target":3
            },
            {
                "source":1,
                "target":15
            },
            {
                "source":2,
                "target":4
            },
            {
                "source":2,
                "target":5
            },
            {
                "source":3,
                "target":4
            },
            {
                "source":3,
                "target":6
            },
            {
                "source":4,
                "target":7
            },
            {
                "source":5,
                "target":8
            },
            {
                "source":5,
                "target":12
            },
            {
                "source":6,
                "target":9
            },
            {
                "source":6,
                "target":13
            },
            {
                "source":7,
                "target":8
            },
            {
                "source":7,
                "target":9
            },
            {
                "source":8,
                "target":10
            },
            {
                "source":9,
                "target":11
            },
            {
                "source":10,
                "target":11
            },
            {
                "source":10,
                "target":16
            },
            {
                "source":11,
                "target":17
            },
            {
                "source":12,
                "target":14
            },
            {
                "source":12,
                "target":16
            },
            {
                "source":13,
                "target":15
            },
            {
                "source":13,
                "target":17
            },
            {
                "source":14,
                "target":19
            },
            {
                "source":15,
                "target":19
            },
            {
                "source":16,
                "target":18
            },
            {
                "source":17,
                "target":18
            },
            {
                "source":18,
                "target":19
            }
        ] 
    }
];
function getOption(graphInfo){
//给节点设置样式
    let nodes=graphInfo['nodes'];
    let links=graphInfo['links'];
    //console.log(links);
//设置option样式
    return {
        title: {
            text: title,
            left: 'center',
            textStyle:{
                fontSize:20
            },
            bottom:0
        },
        tooltip: {
            trigger: 'item'
        },
        backgroundColor:'white',
        roam: true,
        series: [
            {
                type: 'graph',
                layout: 'none',
                symbol: "circle",
                edgeSymbol:['none', 'none'],
                symbolSize: 20,
                edgeSymbolSize: 10,
                nodes: nodes,
                links: links,
                label: {
                    normal: {
                        show: true
                    }
                },
                draggable:true
            }
        ]
    };
}
function nodeStyle(title,x,y){
   return  { 
       name: title,
       x:x,y:y,
       itemStyle: {borderColor: 'black',color:'white',borderWidth: 3},
       label:{
           show:true,position:"inside",
           fontSize:11,color:'black',
           fontWeight:'bold'
        }
    }
}
function edgeStyle(selectNode){
    return {
        source: selectNode[0],
        target: selectNode[1],
        lineStyle: {
            width: 5,
            color: '#000',
            type:'solid',
            opacity:0.8,
            ignoreForceLayout:true
        },
        label:{
             show:false,
             formatter:'{c}',
             fontSize:15
        }
    };
}
//获取节点
function getNodes(Num,nodeLocation){
    let nodes=[];
    //console.log(nodeLocation[0].x);
    let nodeTitle=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
    for(let i=0;i< Num;i++){
        let str="";
        for(let j=0;j<=parseInt(i/26);j++){
            str+=nodeTitle[i-parseInt(i/26)*26];
        }
        nodes.push(nodeStyle(str,nodeLocation[i].x,nodeLocation[i].y))
    }
    return nodes;
}
//导入边
function getLoadLinks(){
   let links1=[];
   let edgeList=graphItem.edgeList;
   let len=edgeList.length;
   for(let i=0;i<len;i++){
      links1.push(edgeStyle([edgeList[i].source,edgeList[i].target]))
   }
   return links1;
}
//初始化数据
function initData(){
    nodes=[],links=[],option={},title="";
    showEdgeIndex=0;
    edgeList=[];
    hamiltonianCycleSet=null;
    pathIndex=-1;
}
function initEdge(){
    for(let i=0;i<links.length;i++){
        option.series[0].links[i].lineStyle.color="black";
        option.series[0].links[i].lineStyle.width=5;
    }
    myChart.setOption(option);
}
//由字母获取 下标  eulerianPathSet转 每一条边 逐步显示
function getIndex(letter){
  let nodeTitle=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
  let len=letter.length;
  let l=letter[0];
  let index=getArrayIndex(nodeTitle,l);
  return index+26*(len-1);
}
function getArrayIndex(arr, obj) {
    var i = arr.length;
    while (i--) {
        if (arr[i] === obj) {
            return i;
        }
    }
    return -1;
}
//显示红色
function showLinksRed(index1,index2){
    let index=0;
    for(let i=0;i<links.length;i++){
        if((links[i].source==index1&&links[i].target==index2)||(links[i].source==index2&&links[i].target==index1))
        {
            index=i;
            break;
        }
    }
    option.series[0].links[index].lineStyle.color="red";
    option.series[0].links[index].lineStyle.width=10;
    myChart.setOption(option);
}
//逐步显示过程
function nextEdges(){
    let newNodeDegree=[];
    if(edgeTreeList.length==0){
        modalApp.modalAlert('显示完毕');
        return;
    }
    for(let i=0;i<nodeDegree.length;i++){
        let str=nodeDegree[i].split('-')[0];
        let w=nodeDegree[i].split('-')[1];
        for(let j=0;j<edgeTreeList.length;j++){
            if(edgeTreeList[j].source==str){
                let t=showLinksRed(getIndex(str),getIndex(edgeTreeList[j].target),w);
                newNodeDegree.push(edgeTreeList[j].target+"-"+t);
                edgeTreeList.splice(j,1);j--;
            }
            else if(edgeTreeList[j].target==str){
                let t=showLinksRed(getIndex(str),getIndex(edgeTreeList[j].source),w);
                newNodeDegree.push(edgeTreeList[j].source+"-"+t);
                edgeTreeList.splice(j,1);j--;
            }
            else{}
        }
    }
    nodeDegree=newNodeDegree;
    myChart.setOption(option);     
}
function Hamiltonian(){
    nodeDegree=[];
    title="哈密尔顿图";
    let vertexList=[];
    const graph = new Graph();
    for(let i=0;i<nodes.length;i++){
        let obj=new GraphVertex(nodes[i].name);
        vertexList.push(obj);
        graph.addVertex(obj);
    }
    for(let j=0;j<links.length;j++){
        graph.addEdge(new GraphEdge(vertexList[links[j].source], vertexList[links[j].target],links[j].value))
    }
    hamiltonianCycleSet = hamiltonianCycle(graph);
    //console.log(hamiltonianCycleSet);
    modalApp.modalAlert('运行成功,请选择路径');
    app.showPathes();
}

let myChart = echarts.init(document.getElementById('echartsDiv'));
let graphItem=[]; //显示的样图数据
let nodes=[],links=[],option={},title="";  //显示图的点集和边集
let showEdgeIndex=0;  //逐步显示边的下标
let nodeDegree=[];
let hamiltonianCycleSet;
let edgeList=[]; //
let pathIndex=-1;
var app=new Vue({
    el: '#app',
    data: {
      exampleGraph1:[
          {
              name:"样图1",
              imgUrl:"res/image/h.png"
          }
      ],
      examples:[],
      showPath:false
    },
    methods:{
        showGraph(index){
            initData();
            //console.log(index);
            graphItem=exampleGraph[index];
            nodes=getNodes(graphItem.nodeNum,graphItem.nodeLocation);
            links=getLoadLinks();
            let jsonData={"nodes":nodes,"links":links}
            option=getOption(jsonData);
            myChart.setOption(option);
        },
        showGraphPath(index){
            initEdge();
            if(pathIndex !=-1){
                this.examples[pathIndex].color='black';
                this.examples[pathIndex].bgColor='white';
            }
            pathIndex=index;
            this.examples[index].color='white';
            this.examples[index].bgColor='black';
            edgeList=hamiltonianCycleSet[index];
            showEdgeIndex=0;
            modalApp.modalAlert('路径载入成功，请点击下一步进行逐步显示');
            
        },
        algorithmRun(){
            //显示过程
            if(nodes.length>0)
            Hamiltonian();
            else{
                modalApp.modalAlert('未选择图形');
            }
        },
        showNext(){
            if(edgeList.length>0){
                //console.log(edgeList);
                if(showEdgeIndex<(edgeList.length-1)){
                    showLinksRed(getIndex(edgeList[showEdgeIndex].value),getIndex(edgeList[showEdgeIndex+1].value))
                    showEdgeIndex++;
                }
                else{
                    modalApp.modalAlert('显示完毕');
                }
            }
            else{
                modalApp.modalAlert('未选择路径');
                
            }
        },
        resetProcess(){
            this.examples[pathIndex].color='black';
            this.examples[pathIndex].bgColor='white';
            pathIndex=-1;
            showEdgeIndex=0;
            nodes=getNodes(graphItem.nodeNum,graphItem.nodeLocation);
            links=getLoadLinks();
            let jsonData={"nodes":nodes,"links":links}
            option=getOption(jsonData);
            myChart.setOption(option);
        },
        showPathes(){
            for(let i=0;i<hamiltonianCycleSet.length;i++){
                this.examples.push({
                    color:'black',
                    bgColor:'white',
                    content:'路径'+(i+1)
                });
            }
            this.showPath=true;
        }
    }
})
var modalApp=new Vue({
    el:"#myModal1",
    data:{
        message:""
    },
    methods:{
        modalAlert(str){
            this.message=str;
            $('#myModal1').modal('toggle');
        }
    }
})